/*
* Revision of last commit: $Rev$
* Author of last commit: $Author$
* Date of last commit: $Date$
*/

#include "stdafx.h"
#include "Trace.h"
#include "Assert.h"
#include <fstream>

namespace Core
{
namespace Cmn
{
namespace
{
/**
@brief This class should be used for logging.
@descr It is like a universal interface for every logging level.
	   But be sure that all trace macro are excluded from build in release
*/
class CLogger
{
public:
	CLogger()
		: m_TracePath("traces.txt")		// hardcode - parameter
	{
		m_TraceStream.open(m_TracePath.c_str());
		assert(!m_TraceStream.bad());
	}

	~CLogger() throw()
	{
		m_TraceStream.close();
	}

	CLogger& operator << (const std::string& szTraceMsg) throw()
	{
		m_TraceStream << szTraceMsg;
		return *this;
	}

	CLogger& operator << (const char* szTraceMsg) throw()
	{
		m_TraceStream << szTraceMsg;
		return *this;
	}

	void flush() throw()
	{
		m_TraceStream << std::endl;
	}
private:
	std::string m_TracePath;
	std::ofstream m_TraceStream;
};

static CLogger gl_Logger;

} //namespace

CTracer& CTracer::operator << (const std::string& szMessage) throw()
{
	gl_Logger << szMessage;
	gl_Logger.flush();
	return *this;
}

CTracer& CTracer::operator << (const char* const szMessage) throw()
{
	gl_Logger << szMessage;
	gl_Logger.flush();
	return *this;
}

CFuncTracer::CFuncTracer(const std::string& strMessage) throw()
 : m_strMessage(strMessage)
{
	gl_Logger << "FUNCTION " << m_strMessage << "STATUS : BEGIN";
	gl_Logger.flush();
}

CFuncTracer::~CFuncTracer() throw()
{
	if (std::uncaught_exception())
	{
		gl_Logger << "FUNCTION " << m_strMessage << "STATUS : EXCEPTION";
	}
	else
	{
		gl_Logger << "FUNCTION " << m_strMessage << "STATUS : DONE";
	}
	gl_Logger.flush();
}

} //namespace Cmn
} //namespace Core